use serde::Deserialize;
use std::fs;

#[derive(Debug, Deserialize)]
pub struct Config {
    pub tasks: Vec<TaskConfig>,
    pub schedule: ScheduleConfig,
}

#[derive(Debug, Deserialize, Clone)]
pub struct TaskConfig {
    pub name: String,
    pub enabled: bool,
    pub proxy: Option<String>,               // 任务级代理
    pub accounts: Vec<AccountConfig>,        // 账号列表
    pub start_hour: Option<u32>,             // 单独设置开始时间(小时)
    pub end_hour: Option<u32>,               // 单独设置结束时间(小时)
    pub start_time: Option<String>,          // 单独设置开始时间(HH:MM:SS格式)
    pub end_time: Option<String>,            // 单独设置结束时间(HH:MM:SS格式)
    pub min_interval_hours: Option<u32>,     // 单独设置最小间隔
    pub min_executions_per_day: Option<u32>, // 单独设置每天最小次数
    pub max_executions_per_day: Option<u32>, // 单独设置每天最大次数
    pub fixed_executions_per_day: Option<u32>, // 单独设置每天固定次数(优先级最高)
    pub total_days: Option<u32>,             // 单独设置总执行天数
}

#[derive(Debug, Deserialize, Clone)]
pub struct AccountConfig {
    pub nickname: String,
    pub enabled: bool,
    pub authorization: String,               // 认证token
    #[allow(dead_code)]
    pub cookie: Option<String>,              // 可选的cookie
    pub proxy: Option<String>,               // 账号级代理(优先级高于任务级)
    // 账号级调度配置(可选,覆盖任务级)
    pub start_hour: Option<u32>,
    pub end_hour: Option<u32>,
    pub start_time: Option<String>,
    pub end_time: Option<String>,
    pub min_interval_hours: Option<u32>,
    pub min_executions_per_day: Option<u32>,
    pub max_executions_per_day: Option<u32>,
    pub fixed_executions_per_day: Option<u32>,
    pub total_days: Option<u32>,
}

#[derive(Debug, Deserialize)]
pub struct ScheduleConfig {
    pub mode: String, // "immediate" or "auto"
    pub start_hour: Option<u32>,             // 开始时间（小时）
    pub end_hour: Option<u32>,               // 结束时间（小时）
    pub start_time: Option<String>,          // 开始时间（HH:MM:SS格式，优先级高于start_hour）
    pub end_time: Option<String>,            // 结束时间（HH:MM:SS格式，优先级高于end_hour）
    pub min_interval_hours: Option<u32>,
    pub min_executions_per_day: Option<u32>, // 每天最小执行次数
    pub max_executions_per_day: Option<u32>, // 每天最大执行次数
    pub fixed_executions_per_day: Option<u32>, // 每天固定执行次数（优先级最高）
    pub total_days: Option<u32>, // 总执行天数
}

impl Config {
    pub fn from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let content = fs::read_to_string(path)?;
        let config: Config = toml::from_str(&content)?;
        Ok(config)
    }

    pub fn get_enabled_tasks(&self) -> Vec<String> {
        self.tasks
            .iter()
            .filter(|task| task.enabled)
            .map(|task| task.name.clone())
            .collect()
    }

    /// 验证并规范化配置
    pub fn validate(&mut self) -> Result<(), String> {
        for task in &mut self.tasks {
            if task.accounts.is_empty() {
                return Err(format!("Task '{}' has no accounts configured", task.name));
            }
            
            for account in &task.accounts {
                if account.nickname.is_empty() {
                    return Err(format!("Task '{}' has an account with empty nickname", task.name));
                }
                if account.authorization.is_empty() {
                    return Err(format!("Account '{}' in task '{}' has empty authorization", account.nickname, task.name));
                }
            }
        }
        Ok(())
    }

    /// 获取账号唯一标识(用于内存中的key)
    pub fn get_account_key(task_name: &str, nickname: &str) -> String {
        format!("{}:{}", task_name, nickname)
    }

    /// 获取账号的安全文件名(用于持久化文件)
    pub fn get_safe_filename(account_key: &str) -> String {
        // 转义所有可能在文件名中有问题的字符,并限制长度
        let safe = account_key
            .replace(['/', '\\', ':', '*', '?', '"', '<', '>', '|', '@'], "_")
            .chars()
            .filter(|c| c.is_alphanumeric() || *c == '_' || *c == '-' || *c == '.')
            .take(200) // 限制文件名长度,为扩展名和路径留空间
            .collect::<String>();
        
        if safe.is_empty() {
            "default".to_string()
        } else {
            safe
        }
    }
}

/// 解析时间字符串 "HH:MM:SS" 返回 (hour, minute, second)
pub fn parse_time_string(time_str: &str) -> Result<(u32, u32, u32), String> {
    let parts: Vec<&str> = time_str.split(':').collect();
    
    if parts.len() != 3 {
        return Err(format!("Invalid time format '{}', expected HH:MM:SS", time_str));
    }
    
    let hour = parts[0].parse::<u32>()
        .map_err(|_| format!("Invalid hour in '{}'", time_str))?;
    let minute = parts[1].parse::<u32>()
        .map_err(|_| format!("Invalid minute in '{}'", time_str))?;
    let second = parts[2].parse::<u32>()
        .map_err(|_| format!("Invalid second in '{}'", time_str))?;
    
    if hour >= 24 {
        return Err(format!("Hour must be 0-23, got {}", hour));
    }
    if minute >= 60 {
        return Err(format!("Minute must be 0-59, got {}", minute));
    }
    if second >= 60 {
        return Err(format!("Second must be 0-59, got {}", second));
    }
    
    Ok((hour, minute, second))
}
